from PyQt5.QtWidgets import QApplication,QMainWindow,QMessageBox,QWidget,QFileDialog
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import QTimer,Qt
import sys
import os
import os.path
from docx import Document
import find_text
import resource
import threading

class texts():
    def __init__(self):
        self.app = QApplication(sys.argv)
        self.window = QWidget()
        self.ui = find_text.Ui_window()
        self.ui.setupUi(self.window)
        self.ui.choose_files_button.clicked.connect(self.select_file)
        self.ui.keywords_button.clicked.connect(self.check_key_words)
        self.ui.startfind_button.clicked.connect(self.read_data)
        self.ui.clear_button.clicked.connect(self.clear)
        self.window.setWindowIcon(QIcon(":/winlogo.ico"))
        self.ui.choose_files_button.setIcon(QIcon(":/file.ico"))
        self.ui.startfind_button.setIcon(QIcon(":/start.ico"))
        self.ui.clear_button.setIcon(QIcon(":/clear.ico"))
        self.ui.keywords_button.setIcon(QIcon(":/confirm.ico"))

        self.Flag = False  # 定义一个常量


    # 选择文件所在的文件夹，并将其输入到对应的框中显示
    def select_file(self):
        self.path = QFileDialog.getExistingDirectory()
        self.ui.filedir_line.setText(self.path)


    # 从文件位置框中获取路径，并得到此文件夹下所有的合适文件路径，然后以列表的形式返回
    def get_path(self):
        self.path = self.ui.filedir_line.text()
        file_list = os.listdir(self.path)  # 获取文件夹下所有文件夹的名称
        self.word_file_list = []  # 这个列表用来存放拼接好的文件夹的路径
        self.file_path = []  # 这个列表用来存放拼接好的所有word文件的路径
        for f in file_list:
            if f.endswith('.docx'):
                self.file_path.append(f)
            else:
                self.word_file_list.append(self.path + '/' + f)
        # print(self.word_file_list)
        for words_file in self.word_file_list:
            for word_docx in os.listdir(words_file):
                if word_docx.endswith('.docx'):
                    self.file_path.append(words_file + '/' + word_docx)
        return self.file_path

    # 从关键字输入框中获取用户输入的关键词，并以列表的形式返回
    def get_key_words(self):
        words = self.ui.keywords_line.text()
        self.key_words=(words.split(' '))
        # print(self.key_words)
        return self.key_words

    # 检查用户输入的关键词中是否有空格，用弹框的形式告诉用户。如果不排除多余的空格会匹配很多符合项。
    def check_key_words(self):
        self.words = self.get_key_words()
        if '' in self.words:
            QMessageBox.information(self.ui.keywords_button,'重要提示：',"<font color='red' size='+1' face='Sans'>'输入的关键字里面有多余的空格，请清除！'</font>")
        else:
            QMessageBox.information(self.ui.keywords_button,'温馨提示：',"<font color='#2EC4B6' size='+1' face='Sans'>'输入正确！'</font>")

    # 读取word里面的段落，判断用户查找的关键词是否存在于段落之中
    def read_paragraphs(self,document, key_word, file_path):
        try:
            for para in document.paragraphs:  # 读取word里面的段落
                for run in para.runs:
                    if key_word in run.text:
                        self.ui.plainText.appendPlainText(f'{file_path.split("/")[-1]}   文件的（段落）里有你搜索的词  {key_word}\n')
                        # print('{}   文件的（段落）里有你搜索的词  {}'.format(file_path, key_word))
                        self.Flag = True
                        # print('key_word paragraphs is {}'.format(flag))
                    else:
                        continue
        except:
            QMessageBox.information(self.ui.startfind_button, '温馨提示：',
                                    "<font color='#2EC4B6' size='+1' face='Sans'>'读取段落错误！'</font>")

    # 读取word里面的表格，判断用户查找的关键词是否存在于表格之中
    def read_tables(self, document, key_word, file_path):
        try:
            for table in document.tables:
                for row in table.rows:
                    for cell in row.cells:
                        if key_word in cell.text:
                            self.ui.plainText.appendPlainText(f'{file_path.split("/")[-1]}   文件的（表格）里有你搜索的词  {key_word}\n')
                            # print('{}   文件的（表格）里有你搜索的词  {}'.format(file_path, key_word))
                            self.Flag = True
                        else:
                            continue
        except:
            QMessageBox.information(self.ui.startfind_button, '温馨提示：',
                                    "<font color='#2EC4B6' size='+1' face='Sans'>'读取表格错误！'</font>")

    # 读取页眉中的段落，并搜索关键词
    def header_paragraph(self, header, even_header, key_word, file_path):
        for para in header.paragraphs:
            if key_word in para.text:
                self.ui.plainText.appendPlainText(f'{file_path.split("/")[-1]}   文件（页眉）段落里有你搜索的词  {key_word}\n')
                # print('{}   文件（页眉/页脚）有你搜索的词  {}'.format(file_path, key_word))
                self.Flag = True
            else:
                continue

        for para in even_header.paragraphs:
            if key_word in para.text:
                self.ui.plainText.appendPlainText(f'{file_path.split("/")[-1]}   文件（页眉）段落里有你搜索的词  {key_word}\n')
                # print('{}   文件（页眉/页脚）有你搜索的词  {}'.format(file_path, key_word))
                self.Flag = True
            else:
                continue

    # 读取页眉中的表格，并搜索关键词
    def header_table(self, header, even_header, key_word, file_path):
        for table in header.tables:
            for row in table.rows:
                for cell in row.cells:
                    if key_word in cell.text:
                        self.ui.plainText.appendPlainText(
                            f'{file_path.split("/")[-1]}   文件（页眉）表格里有你搜索的词  {key_word}\n')
                        self.Flag = True
                    else:
                        continue

        for table in even_header.tables:
            for row in table.rows:
                for cell in row.cells:
                    if key_word in cell.text:
                        self.ui.plainText.appendPlainText(
                            f'{file_path.split("/")[-1]}   文件（页眉）表格里有你搜索的词  {key_word}\n')
                        self.Flag = True
                    else:
                        continue

    # 读取页脚中的段落，并搜索关键词
    def footer_paragraph(self, footer, even_footer, key_word, file_path):
        for para in footer.paragraphs:
            if key_word in para.text:
                self.ui.plainText.appendPlainText(f'{file_path.split("/")[-1]}   文件（页脚）段落里有你搜索的词  {key_word}\n')
                # print('{}   文件（页眉/页脚）有你搜索的词  {}'.format(file_path, key_word))
                self.Flag = True
            else:
                continue

        for para in even_footer.paragraphs:
            if key_word in para.text:
                self.ui.plainText.appendPlainText(f'{file_path.split("/")[-1]}   文件（页脚）段落里有你搜索的词  {key_word}\n')
                # print('{}   文件（页眉/页脚）有你搜索的词  {}'.format(file_path, key_word))
                self.Flag = True
            else:
                continue

    # 读取页脚中的表格，并搜索关键词
    def footer_table(self, footer, even_footer, key_word, file_path):
        for table in footer.tables:
            for row in table.rows:
                for cell in row.cells:
                    if key_word in cell.text:
                        self.ui.plainText.appendPlainText(
                            f'{file_path.split("/")[-1]}   文件（页脚）表格里有你搜索的词  {key_word}\n')
                        self.Flag = True
                    else:
                        continue

        for table in even_footer.tables:
            for row in table.rows:
                for cell in row.cells:
                    if key_word in cell.text:
                        self.ui.plainText.appendPlainText(
                            f'{file_path.split("/")[-1]}   文件（页脚）表格里有你搜索的词  {key_word}\n')
                        self.Flag = True
                    else:
                        continue

    # 读取word文件里面的页眉和页脚，判断用户查找的关键词是否存在于页眉和页脚之中
    def read_header_footer(self,document, key_word, file_path):
        try:
            section = document.sections[0]
            header = section.header
            footer = section.footer
            even_footer = section.even_page_footer
            even_header = section.even_page_header
            header_para = threading.Thread(target=self.header_paragraph, args=(header, even_header, key_word,file_path))
            header_table = threading.Thread(target=self.header_table, args=(header, even_header, key_word, file_path))
            footer_para = threading.Thread(target=self.footer_paragraph, args=(footer, even_footer, key_word, file_path))
            footer_table = threading.Thread(target=self.footer_table, args=(footer, even_footer, key_word, file_path))
            header_para.start()
            header_table.start()
            footer_para.start()
            footer_table.start()
        except:
            QMessageBox.information(self.ui.startfind_button, '温馨提示：',
                                    "<font color='#2EC4B6' size='+1' face='Sans'>'读取页眉页脚错误！'</font>")

    # 给查找文件添加进度条显示
    def progressBar(self,value):
        self.ui.progressBar.reset()
        self.ui.progressBar.setValue(value)

    # 读取word文档数据，并查找关键词是否存在在文档中
    def read_data(self):
        key_words = self.get_key_words()
        path = self.get_path()
        for num in range(len(path)):
            file_path = path[num]
            print('正在处理第{}个文件，总共有{}个文件要处理！'.format(num+1,len(path)))
            processValue = ((num+1)/len(path))*100
            self.ui.progressBar.setValue(processValue)
            for key_word in key_words:
                doc = Document(file_path)
                paragraph = threading.Thread(target=self.read_paragraphs,
                                             args=(doc, key_word, file_path))  # 调用段落函数，判断关键字是否在段落之中，并将状态码返回
                table = threading.Thread(target=self.read_tables,
                                         args=(doc, key_word, file_path))  # 调用表格函数，判断关键字是否在表格之中，并将状态码返回
                header_footer = threading.Thread(target=self.read_header_footer,
                                                 args=(doc, key_word, file_path))  # 调用页眉页脚函数，判断关键字是否在页眉或者页脚之中，并将状态码返回
                paragraph.start()
                table.start()
                header_footer.start()
        self.get_Flag()


    def get_Flag(self):
        if self.Flag == False:  # 状态码的类型判断。其实状态码只是为了告诉用户程序运行完成了，并且没有搜到关键词时。
            self.ui.plainText.appendPlainText('* ' * 50 + '\n')
            self.ui.plainText.appendPlainText(f'您要搜索词没有找到！！！\n')
            self.ui.plainText.appendPlainText('* ' * 50 + '\n')
        else:
            pass


    # 清楚显示框中的文档
    def clear(self):
        self.ui.plainText.clear()
        self.ui.progressBar.reset()
        self.Flag = False

    def main(self):
        self.window.show()
        sys.exit(self.app.exec_())

if __name__ == '__main__':
    wind = texts()
    wind.main()



